package main

import (
	"fmt"
	"io"
	"math"
	"sort"
	"strings"
)

// ==========================================
// 基本接口定义
// ==========================================

// Greeter 接口定义了打招呼的方法
type Greeter interface {
	Greet() string
}

// Speaker 接口定义了发声的方法
type Speaker interface {
	Speak() string
}

// ==========================================
// 实现接口的结构体
// ==========================================

// Chinese 结构体
type Chinese struct {
	Name string
}

// 实现Greeter接口
func (c Chinese) Greet() string {
	return fmt.Sprintf("你好，我是%s", c.Name)
}

// 实现Speaker接口
func (c Chinese) Speak() string {
	return "我说中文"
}

// English 结构体
type English struct {
	Name string
}

// 实现Greeter接口
func (e English) Greet() string {
	return fmt.Sprintf("Hello, I'm %s", e.Name)
}

// 实现Speaker接口
func (e English) Speak() string {
	return "I speak English"
}

// ==========================================
// 接口组合
// ==========================================

// 组合多个接口
type Communicator interface {
	Greeter
	Speaker
}

// ==========================================
// 几何图形的例子
// ==========================================

// Shape 接口
type Shape interface {
	Area() float64
	Perimeter() float64
}

// Circle 结构体
type Circle struct {
	Radius float64
}

// 实现Shape接口
func (c Circle) Area() float64 {
	return math.Pi * c.Radius * c.Radius
}

func (c Circle) Perimeter() float64 {
	return 2 * math.Pi * c.Radius
}

// Rectangle1 结构体
type Rectangle1 struct {
	Width  float64
	Height float64
}

// 实现Shape接口
func (r Rectangle1) Area() float64 {
	return r.Width * r.Height
}

func (r Rectangle1) Perimeter() float64 {
	return 2 * (r.Width + r.Height)
}

// ==========================================
// 自定义排序的例子
// ==========================================

// Person3 结构体
type Person3 struct {
	Name string
	Age  int
}

// ByAge 实现sort.Interface接口
type ByAge []Person3

func (a ByAge) Len() int           { return len(a) }
func (a ByAge) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }

func main() {
	// ==========================================
	// 基本接口使用
	// ==========================================

	// 创建实现了接口的结构体实例
	chinese := Chinese{Name: "张三"}
	english := English{Name: "John"}

	// 使用接口类型的变量
	var greeter Greeter
	greeter = chinese
	fmt.Println(greeter.Greet())

	greeter = english
	fmt.Println(greeter.Greet())

	// 使用组合接口
	var communicator Communicator
	communicator = chinese
	fmt.Println(communicator.Greet())
	fmt.Println(communicator.Speak())

	// ==========================================
	// 几何图形接口使用
	// ==========================================

	// 创建形状
	circle := Circle{Radius: 5}
	rectangle := Rectangle1{Width: 4, Height: 6}

	// 使用接口类型的切片存储不同的形状
	shapes := []Shape{circle, rectangle}

	// 遍历并计算面积和周长
	for _, shape := range shapes {
		fmt.Printf("面积: %.2f\n", shape.Area())
		fmt.Printf("周长: %.2f\n", shape.Perimeter())
	}

	// ==========================================
	// 空接口
	// ==========================================

	// 空接口可以存储任何类型的值
	var i interface{}
	i = 42
	fmt.Printf("空接口存储整数: %v\n", i)

	i = "Hello"
	fmt.Printf("空接口存储字符串: %v\n", i)

	i = Person3{Name: "张三", Age: 25}
	fmt.Printf("空接口存储结构体: %v\n", i)

	// 使用空接口切片存储不同类型的值
	mixed := []interface{}{42, "Hello", true, 3.14}
	for _, v := range mixed {
		fmt.Printf("类型:%T 值:%v\n", v, v)
	}

	// ==========================================
	// 类型断言
	// ==========================================

	// 基本类型断言
	var val interface{} = "Hello, Go"

	if str, ok := val.(string); ok {
		fmt.Printf("值是字符串: %s\n", str)
	}

	if _, ok := val.(int); !ok {
		fmt.Println("值不是整数")
	}

	// 使用switch进行类型判断
	checkType(42)
	checkType("Hello")
	checkType(true)
	checkType(3.14)

	// ==========================================
	// 自定义排序
	// ==========================================

	// 创建Person切片
	people := []Person3{
		{"张三", 30},
		{"李四", 25},
		{"王五", 35},
	}

	// 按年龄排序
	sort.Sort(ByAge(people))
	fmt.Println("\n按年龄排序后的结果:")
	for _, p := range people {
		fmt.Printf("%s: %d岁\n", p.Name, p.Age)
	}

	// ==========================================
	// 常用标准库接口
	// ==========================================

	// io.Writer接口示例
	var builder strings.Builder
	io.WriteString(&builder, "Hello, ")
	io.WriteString(&builder, "Go!")
	fmt.Printf("\nBuilder内容: %s\n", builder.String())

	// ==========================================
	// 接口的nil值和nil接口
	// ==========================================

	var s Shape
	fmt.Printf("未初始化的接口是否为nil: %v\n", s == nil)

	var p *Person3
	var i2 interface{} = p
	fmt.Printf("存储nil指针的接口是否为nil: %v\n", i2 == nil)

	// ==========================================
	// 练习
	// ==========================================

	// 1. 创建一个Animal接口，定义基本的动物行为（如吃、睡、叫等），
	//    然后创建几个实现这个接口的具体动物类型

	// 2. 实现一个简单的日志接口，定义不同级别的日志方法，
	//    然后创建控制台日志和文件日志两种实现

	// 3. 创建一个数据库接口，定义基本的CRUD操作，
	//    然后实现MySQL和MongoDB两种具体实现（模拟即可）

	// 4. 实现一个缓存接口，定义获取和设置方法，
	//    然后创建内存缓存和Redis缓存两种实现（模拟即可）

	// 5. 创建一个支付接口，定义支付方法，
	//    然后实现支付宝和微信支付两种具体实现（模拟即可）
}

// 类型检查函数
func checkType(i interface{}) {
	switch v := i.(type) {
	case int:
		fmt.Printf("整数: %d\n", v)
	case string:
		fmt.Printf("字符串: %s\n", v)
	case bool:
		fmt.Printf("布尔值: %t\n", v)
	default:
		fmt.Printf("未知类型: %T\n", v)
	}
}

// ==========================================
// 练习参考实现
// ==========================================

// 1. Animal接口示例
type Animal interface {
	Eat() string
	Sleep() string
	MakeSound() string
}

type Dog struct {
	Name string
}

func (d Dog) Eat() string {
	return fmt.Sprintf("%s正在吃骨头", d.Name)
}

func (d Dog) Sleep() string {
	return fmt.Sprintf("%s正在睡觉", d.Name)
}

func (d Dog) MakeSound() string {
	return fmt.Sprintf("%s: 汪汪汪!", d.Name)
}

// 2. Logger接口示例
type Logger1 interface {
	Debug(msg string)
	Info(msg string)
	Error(msg string)
}

type ConsoleLogger struct{}

func (l ConsoleLogger) Debug(msg string) {
	fmt.Printf("[DEBUG] %s\n", msg)
}

func (l ConsoleLogger) Info(msg string) {
	fmt.Printf("[INFO] %s\n", msg)
}

func (l ConsoleLogger) Error(msg string) {
	fmt.Printf("[ERROR] %s\n", msg)
}

// 3. Database接口示例
type Database interface {
	Connect() error
	Create(data interface{}) error
	Read(id int) (interface{}, error)
	Update(id int, data interface{}) error
	Delete(id int) error
}

// 4. Cache接口示例
type Cache1 interface {
	Get(key string) (interface{}, error)
	Set(key string, value interface{}) error
	Delete(key string) error
}

// 5. Payment接口示例
type Payment interface {
	Pay(amount float64) error
	Refund(amount float64) error
	GetBalance() float64
}
